/* ex: set tabstop=4 shiftwidth=4 expandtab: */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/socket.h>

#include "rtsp.h"
#include "event.h"
#include "base64.h"

#define LFXMSG_REQ \
	"LFX_MSG * RTSP/1.0\r\n"\
	"CSeq: %d\r\n"\
	"Content-Length: %d\r\n"\
	"\r\n"

#define LFXMSG_PAYLOAD \
	"g=%s\r\n"\
	"t=%d\r\n"\
	"l=%d\r\n"\
	"d=%s\r\n"

typedef struct {
	char *g;
	int t;
	int len;
	char d[1024];
} lfxmsg_req_t;

static int
make_lfxmsg(char *buf, int cseq, lfxmsg_req_t *req)
{
	static char dbuf[1024] = {0}; /* d string buf */
	static char rbuf[1024] = {0}; /* payload buf */
	int len;

	base64_encode(dbuf, req->d, req->len);
	len = sprintf(rbuf, LFXMSG_PAYLOAD, req->g, req->t, req->len, dbuf); /* XXX should be optimized */
	len = sprintf(buf, LFXMSG_REQ LFXMSG_PAYLOAD, cseq, len, req->g, req->t, req->len, dbuf);

	return len;
}

static lfxmsg_req_t req_uircom = {
	.g = "UiRcom",
	.t = 0,
	.len = 279,
	.d = {
		0x01, 0x01, 0x12, 0x14, 0x9A, 0x00, 0x01, 0x01, 
		0x55, 0x53, 0x00, 0x00, 0x01, 0x3D, 0x00, 0x0A, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C,
	},
};

static lfxmsg_req_t req_uircom2 = {
	.g = "UiRcom",
	.t = 0,
	.len = 279,
	.d = {
		0x01, 0x01, 0x12, 0x14, 0x9A, 0x00, 0x01, 0x02, 
		0x55, 0x53, 0x00, 0x00, 0x01, 0x10, 0x00, 0x01, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
	},
};

static lfxmsg_req_t req_netav = {
	.g = "NETAV",
	.t = 1,
	.len = 44,
	.d = {
		0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
		0x03, 0x00, 0x00, 0x00, 0x41, 0x4C, 0x49, 0x56, 
		0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 
	},
};

static lfxmsg_req_t req_netav2 = {
	.g = "NETAV",
	.t = 1,
	.len = 44,
	.d = {
		0xF4, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
		0x03, 0x00, 0x00, 0x00, 0x41, 0x4C, 0x49, 0x56, 
		0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
		0x00, 0x00, 0x00, 0x00, 
	},
};

static lfxmsg_req_t req_ping = {
	.g = "ping",
	.t = 0,
	.len = 0,
};

static lfxmsg_req_t req_tv = {
	.g = "TV",
	.t = 2,
	.len = 48,
	.d = {
		0x13, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 
		0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	},
};

static void
lfxmsg_send_cb(void *arg)
{
	rtsp_session_t *sess = arg;
	rtsp_channel_t *ch = sess->chn_get;
	char *buf;
	int len;

	if (!ch)
		return;

	buf = ch->buf;

	len = make_lfxmsg(buf, 3, &req_tv);
	printf("LFX_MSG REQ:[%s]\n", buf);
	send(ch->fd, buf, len, 0);
}

void
lfxmsg_start(rtsp_session_t *sess)
{
	sched_event(5000, lfxmsg_send_cb, sess);
}

#define LFX_MSG_RESP \
	"RTSP/1.0 200 OK\r\n"\
	"%s\r\n"\
	"\r\n"

static char *
get_line(char *req, char *head, char *buf)
{
	char *q = buf;
	char *p = strstr(req, head);

	if (!p)
		return NULL;
	while (*p != '\r')
		*q++ = *p++;
	*q = '\0';

	return buf;
}

int
lfxmsg_parse_request(rtsp_session_t *sess, rtsp_channel_t *ch, char *buf)
{
	int len;
	char cseq[256];

	if (!get_line(ch->buf, "CSeq:", cseq))
		return 0;

	if (strncmp(ch->buf, "LFX_MSG", 7) == 0) {
		len = sprintf(buf, LFX_MSG_RESP, cseq);
		send(sess->chn_get->fd, buf, len, 0);
	} else {
		/* ignore the 200 OK resp? */
	}

	ch->buf[0] = '\0';
	ch->len = 0;

	return 0;
}

